import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { UserWallet } from './entities/user-wallet.entity';
import { AdjustWalletDto, AdjustType, AdjustOperation } from './dto/adjust-wallet.dto';
import { User } from '../../users/entities/user.entity';

/**
 * 钱包服务
 */
@Injectable()
export class WalletService {
  constructor(
    @InjectRepository(UserWallet)
    private readonly userWalletRepository: Repository<UserWallet>,
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    private readonly dataSource: DataSource,
  ) {}

  /**
   * 获取用户钱包信息
   */
  async getWallet(userId: number): Promise<UserWallet> {
    let wallet = await this.userWalletRepository.findOne({
      where: { userId },
      relations: ['user'],
    });

    // 如果钱包不存在，创建一个新的
    if (!wallet) {
      wallet = await this.createWallet(userId);
    }

    return wallet;
  }

  /**
   * 创建用户钱包
   */
  async createWallet(userId: number): Promise<UserWallet> {
    // 检查用户是否存在
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException(`用户 ID ${userId} 不存在`);
    }

    const wallet = this.userWalletRepository.create({
      userId,
      balance: 0,
      voucherBalance: 0,
    });

    return await this.userWalletRepository.save(wallet);
  }

  /**
   * 调整钱包余额（管理员功能）
   */
  async adjustWallet(adjustDto: AdjustWalletDto): Promise<UserWallet> {
    const { userId, type, operation, amount, reason } = adjustDto;

    if (amount <= 0) {
      throw new BadRequestException('调账金额必须大于0');
    }

    return await this.dataSource.transaction(async (manager) => {
      let wallet = await manager.findOne(UserWallet, { where: { userId } });
      
      if (!wallet) {
        wallet = await this.createWallet(userId);
      }

      const fieldName = type === AdjustType.BALANCE ? 'balance' : 'voucherBalance';
      const currentAmount = wallet[fieldName];

      let newAmount: number;
      switch (operation) {
        case AdjustOperation.ADD:
          newAmount = currentAmount + amount;
          break;
        case AdjustOperation.SUBTRACT:
          newAmount = currentAmount - amount;
          if (newAmount < 0) {
            throw new BadRequestException(`${type === AdjustType.BALANCE ? '余额' : '代金券余额'}不足`);
          }
          break;
        case AdjustOperation.SET:
          newAmount = amount;
          break;
        default:
          throw new BadRequestException('无效的调账操作');
      }

      wallet[fieldName] = newAmount;
      return await manager.save(UserWallet, wallet);
    });
  }

  /**
   * 增加余额
   */
  async addBalance(userId: number, amount: number): Promise<UserWallet> {
    if (amount <= 0) {
      throw new BadRequestException('金额必须大于0');
    }

    return await this.dataSource.transaction(async (manager) => {
      let wallet = await manager.findOne(UserWallet, { where: { userId } });
      
      if (!wallet) {
        wallet = await this.createWallet(userId);
      }

      wallet.balance += amount;
      return await manager.save(UserWallet, wallet);
    });
  }

  /**
   * 扣除余额
   */
  async deductBalance(userId: number, amount: number): Promise<UserWallet> {
    if (amount <= 0) {
      throw new BadRequestException('金额必须大于0');
    }

    return await this.dataSource.transaction(async (manager) => {
      const wallet = await manager.findOne(UserWallet, { where: { userId } });
      
      if (!wallet || wallet.balance < amount) {
        throw new BadRequestException('余额不足');
      }

      wallet.balance -= amount;
      return await manager.save(UserWallet, wallet);
    });
  }

  /**
   * 增加代金券余额
   */
  async addVoucherBalance(userId: number, amount: number): Promise<UserWallet> {
    if (amount <= 0) {
      throw new BadRequestException('金额必须大于0');
    }

    return await this.dataSource.transaction(async (manager) => {
      let wallet = await manager.findOne(UserWallet, { where: { userId } });
      
      if (!wallet) {
        wallet = await this.createWallet(userId);
      }

      wallet.voucherBalance += amount;
      return await manager.save(UserWallet, wallet);
    });
  }

  /**
   * 扣除代金券余额
   */
  async deductVoucherBalance(userId: number, amount: number): Promise<UserWallet> {
    if (amount <= 0) {
      throw new BadRequestException('金额必须大于0');
    }

    return await this.dataSource.transaction(async (manager) => {
      const wallet = await manager.findOne(UserWallet, { where: { userId } });
      
      if (!wallet || wallet.voucherBalance < amount) {
        throw new BadRequestException('代金券余额不足');
      }

      wallet.voucherBalance -= amount;
      return await manager.save(UserWallet, wallet);
    });
  }
}